import json

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets, pagination
from rest_framework.decorators import action
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.permissions import AllowAny

from app.health_manage.columns import health_manage_columns, get_health_manage_columns_show
from app.health_manage.data_opt import health_basic_data_sync, server_reverse_query, dashboard_selections, dashboard_pie_data
from app.health_manage.filters import ServerHealthFilter
from app.health_manage.models import ServerHealth, ExpertiseHealthList, HealthLevel, ServerLifeScore, FaultFrequencyScore, FaultScore
from app.health_manage.other_models import CustomUserColumns, ConfigOptions
from app.health_manage.serializers import ServerHealthSerializer
from app.health_manage.utils import get_domain_account, get_dict_value, is_float
from common.libs.common import jsonify
from common.libs.common_data_opt import common_export


class AllPagination(pagination.PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 50000


class ServerHealthViewSet(viewsets.ModelViewSet):
    queryset = ServerHealth.objects.all()
    serializer_class = ServerHealthSerializer

    permission_classes = [AllowAny]
    pagination_class = AllPagination

    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_class = ServerHealthFilter
    search_fields = ['systemSN', 'manageIp', 'ipmi', 'dataCenter', 'userAccount',
                     'userProductLine', 'manu', 'model', 'health', 'lockStatus', 'lifeTime', 'isDeleted']

    exclude_fields = ['id', 'is_deleted', 'createAt', 'updateAt', 'dataCenter', 'rackBuilding', 'rackFloor', 'rackModule', 'rackCode', 'uLocationStart', 'uLocationEnd']

    def list(self, request, *args, **kwargs):
        total = 0
        data = []
        response = super().list(request, *args, **kwargs)

        if 'results' in response.data:
            data = response.data['results']
            total = response.data['count']
        return jsonify(code=200, success=True, total=total, data=data, )

    @action(detail=False, methods=['get'])
    def health_manage_columns(self, request, *args, **kwargs):
        columns, forms = health_manage_columns()
        columns_show = get_health_manage_columns_show(get_domain_account(request))
        return jsonify(code=200, success=True, columns=columns, forms=forms, columns_show=columns_show)

    @action(detail=False, methods=['post'])
    def sync_health_basic_data(self, request, *args, **kwargs):
        data = request.data
        res, msg = health_basic_data_sync()
        # server_reverse_query()
        res2 = server_reverse_query()
        return jsonify(code=200, success=res, msg='success')

    @action(detail=False, methods=['get'])
    def get_expertise_selections(self, request, *args, **kwargs):
        info = ExpertiseHealthList.objects.filter(isDeleted=0)
        data = []
        for item in info:
            data.append({"label": item.expertise, "value": item.expertise, "health": item.health})

        return jsonify(code=200, success=True, data=data)

    @action(detail=False, methods=['get'])
    def get_fault_type_selections(self, request, *args, **kwargs):
        """获取故障类型选项"""
        info = list(set(list(ConfigOptions.objects.using('server-db').filter(enabled=True, is_deleted=0, config_type='fault_type').values_list('value', flat=True).order_by('-gmt_created'))))
        fault_type = []
        for item in info:
            fault_type.append({"label": item, "value": item})
        health = []
        info2 = list(set(list(HealthLevel.objects.all().values_list('healthLevel', flat=True))))
        for item in info2:
            health.append({"label": item, "value": item})

        fault_level = [{"label": "一般告警", "value": "一般告警"},
                       {"label": "关注告警", "value": "关注告警"},
                       {"label": "严重告警", "value": "严重告警"},
                       {"label": "紧急告警", "value": "紧急告警"}]

        return jsonify(code=200, success=True, data={"fault": fault_type, "expertise": health, "faultLevel": fault_level})

    @action(detail=False, methods=['get'])
    def export_data(self, request, *args, **kwargs):
        """导出数据，使用相同的筛选逻辑"""
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)  # 序列化数据
        raw_data = serializer.data

        field_keys = []
        table_headers = []

        columns, forms = health_manage_columns()
        for field in columns:
            if field.get('prop') not in self.exclude_fields:  # 过滤掉不需要的字段
                field_keys.append(field.get('prop'))
                table_headers.append(field.get('label'))

        table_data = [[item.get(key, '') for key in field_keys] for item in raw_data]
        table_data.insert(0, table_headers)
        res = common_export(table_data, '健康度信息库')
        return res

    @action(detail=False, methods=['post'])
    def update_health_manage_data(self, request, *args, **kwargs):
        """编辑或批量编辑"""
        data = request.data
        u_id = data.get('u_id', None)
        if not u_id:
            return jsonify(code=200, success=False, msg='未获取到资源ID')

        id_list = str(u_id).split(',')
        del data['u_id']
        new_data = get_dict_value(data)
        ServerHealth.objects.filter(id__in=id_list).update(**new_data)
        return jsonify(code=200, success=True, msg='success')

    @action(detail=False, methods=['get'])
    def get_health_config_data(self, request, *args, **kwargs):
        """获取健康度配置数据"""
        params = request.query_params

        health_level = list(HealthLevel.objects.all().values())
        life_score = list(ServerLifeScore.objects.all().values())
        frequency_score = list(FaultFrequencyScore.objects.all().values())
        fault_score = list(FaultScore.objects.all().values())
        expertise_data = list(ExpertiseHealthList.objects.filter(isDeleted=0).values())

        for item in fault_score:
            item['faultType'] = item['faultType'].split(',') if item['faultType'] else []
        for item in life_score:
            item['score'] = str(item['score'])
        for item in frequency_score:
            item['score'] = str(item['score'])

        data = {
            'healthLevel': health_level,
            'lifeScore': life_score,
            'faultRateData': frequency_score,
            'faultScoreData': fault_score,
            'expertiseData': expertise_data
        }
        return jsonify(code=200, success=True, data=data)

    @action(detail=False, methods=['post'])
    def update_health_config_data(self, request, *args, **kwargs):
        """更新健康度配置信息"""
        data = request.data
        c_type = data.get('c_type', None)
        if not c_type:
            return jsonify(code=200, success=False, msg='未获取到数据类型')

        info = json.loads(data.get('data'))
        u_id = info.get('id', None)

        if c_type == 'healthLevel':
            score = info.get('score')
            tmp_list = str(score).strip().split(',')
            start_score = tmp_list[0].replace('[', '')
            end_score = tmp_list[1].replace(']', '')
            HealthLevel.objects.filter(id=u_id).update(score=info.get('score'), startScore=start_score, endScore=end_score)
        elif c_type == 'lifeScore':
            if not u_id and info.get('life') and info.get('lifeDate') and info.get('weight'):
                ServerLifeScore.objects.create(life=info.get('life'), lifeDate=info.get('lifeDate'), score=is_float(info.get('score')),
                                               weight=is_float(info.get('weight')), xid=info.get('_XID')).save()
            else:
                ServerLifeScore.objects.filter(id=u_id).update(life=info.get('life'), lifeDate=info.get('lifeDate'), score=is_float(info.get('score')),
                                               weight=is_float(info.get('weight')), xid=info.get('_XID'))
        elif c_type == 'faultFrequency':
            if not u_id and info.get('score') and info.get('days') and info.get('frequencyName'):
                FaultFrequencyScore.objects.create(days=info.get('days'), frequencyName=info.get('frequencyName'), score=info.get('score'), xid=info.get('_XID')).save()
            else:
                FaultFrequencyScore.objects.filter(id=u_id).update(days=info.get('days'), frequencyName=info.get('frequencyName'), score=info.get('score'), xid=info.get('_XID'))
        elif c_type == 'faultScore':
            # if FaultScore.objects.filter(faultType__icontains=info.get('faultLevel')).exists():
            #     return jsonify(code=200, success=False, msg='该故障等级配置已存在')
            if FaultScore.objects.filter(faultType=','.join(info.get('faultType')), faultLevel=info.get('faultLevel')).exists():
                return jsonify(code=200, success=False, msg='该条设置已存在')
            if not u_id and info.get('score') and info.get('faultType') and info.get('faultLevel'):
                FaultScore.objects.create(faultType=','.join(info.get('faultType')), faultLevel=info.get('faultLevel'), score=info.get('score'), xid=info.get('_XID')).save()
            else:
                FaultScore.objects.filter(id=u_id).update(faultType=','.join(info.get('faultType')), faultLevel=info.get('faultLevel'), score=info.get('score'), xid=info.get('_XID'))
        elif c_type == 'expertise':
            # if ExpertiseHealthList.objects.filter(expertise=info.get('expertise')).exists():
            #     return jsonify(code=200, success=False, msg='该经验已存在')
            if not u_id and info.get('expertise') and info.get('health'):
                ExpertiseHealthList.objects.create(expertise=info.get('expertise'), health=info.get('health'), xid=info.get('_XID')).save()
            else:
                ExpertiseHealthList.objects.filter(id=u_id).update(expertise=info.get('expertise'), health=info.get('health'), xid=info.get('_XID'))
        return jsonify(code=200, success=True, msg='success')

    @action(detail=False, methods=['post'])
    def delete_health_config_data(self, request, *args, **kwargs):
        """更新健康度配置信息"""
        data = request.data
        c_type = data.get('c_type', None)
        tmp = data.get('data', None)
        if not tmp:
            return jsonify(code=200, success=True, msg='success')
        info = json.loads(data.get('data', None))
        u_id = info.get('id', None)

        print(info)
        if c_type == 'lifeScore':
            if u_id:
                ServerLifeScore.objects.filter(id=u_id).delete()
            else:
                ServerLifeScore.objects.filter(xid=info.get('_XID')).delete()
        elif c_type == 'faultFrequency':
            if u_id:
                FaultFrequencyScore.objects.filter(id=u_id).delete()
            else:
                FaultFrequencyScore.objects.filter(xid=info.get('_XID')).delete()
        elif c_type == 'faultScore':
            if u_id:
                FaultScore.objects.filter(id=u_id).delete()
            else:
                FaultScore.objects.filter(xid=info.get('_XID')).delete()
        elif c_type == 'expertise':
            if u_id:
                ExpertiseHealthList.objects.filter(id=u_id).delete()
            else:
                ExpertiseHealthList.objects.filter(xid=info.get('_XID')).delete()
        return jsonify(code=200, success=True, msg='success')

    @action(detail=False, methods=['get'])
    def get_dashboard_selections(self, request, *args, **kwargs):
        data = dashboard_selections()
        return jsonify(code=200, success=True, data=data)

    @action(detail=False, methods=['get'])
    def get_dashboard_pie_data(self, request, *args, **kwargs):
        params = request.query_params
        res, data = dashboard_pie_data(params)
        return jsonify(code=200, success=res, data=data)
# Create your views here.
